package cn.kmsoft.spatialboot.controller;

import cn.kmsoft.spatialboot.config.DbConfig;
import cn.kmsoft.spatialboot.config.JdbcConfig;
import cn.kmsoft.common.utils.StringUtil;
import cn.kmsoft.wololo.object.GeoJson;
import cn.kmsoft.common.RestResponse;
import cn.kmsoft.common.exception.ExceptionMsg;
import cn.kmsoft.common.exception.ServiceException;
import cn.kmsoft.wololo.object.query.AnalysisType;

import cn.kmsoft.wololo.object.query.GeoJsonQuery;
import cn.kmsoft.wololo.object.query.TableQuery;
import cn.kmsoft.spatialboot.service.SpatialAnalysisService;
import io.swagger.annotations.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ExecutionException;

import static org.springframework.util.MimeTypeUtils.APPLICATION_JSON_VALUE;

/**
 * @author
 * @date 2023/5/16
 */
@CrossOrigin
@RestController
@Api(description = "空间叠加分析,包括intersect和difference", tags = "1.Layer Overlay")
@RequestMapping(produces = APPLICATION_JSON_VALUE)
public class LayerOverlayController extends BaseController{
    private static final Logger logger = LoggerFactory.getLogger(LayerOverlayController.class);
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss-SSS");
    private final SpatialAnalysisService spatialAnalysisService;

    //@Autowired
    //private Map<String, DBConfig> dynamicDBConfig;
    @Autowired
    private DbConfig dbConfig;


    @Autowired
    public LayerOverlayController(SpatialAnalysisService spatialAnalysisService) {
        this.spatialAnalysisService = spatialAnalysisService;
    }


    @ApiOperation(value = "空间叠加分析，跨投影度带。以输入图形做面与面的叠加,数据转换到fgeo_wkid投影下。这里需要修改fgeo_wkid参数")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "instanceName", value = "数据库连接实例名,例如zyk_dbfgc", paramType = "path", required = true),
            @ApiImplicitParam(name = "tableId", value = "表ID，带表空间名。例如sde.bgdc_dltb_gjxfb_2022 ", paramType = "path", required = true),
            @ApiImplicitParam(name = "query", value = "geoJson叠加分析查询对象", paramType = "body", required = true, dataType = "GeoJsonQuery")
    })
    @PostMapping(value = "/intersectpy2/{instanceName}/{tableId:.*}")
    public RestResponse intersectPYByGeoJsonWithCrsTransform(@PathVariable String instanceName,
                                                             @PathVariable String tableId,
                                                             @RequestBody GeoJsonQuery query)
            throws ExecutionException, InterruptedException {
        System.out.println();
        String beginTime = sdf.format(new Date());
        System.out.println("*******************提交处理请求*******************," + beginTime);

        JdbcConfig jdbcConfig= dbConfig.getJdbcCconfigByDbKey(instanceName);
        String dbTypeName = jdbcConfig.getDbtypename();

        if (query.getGeoJson().trim().startsWith("{")) {
            if (query.getDigits() == null) {
                query.setDigits(2);
            }
            if (AnalysisType.INTERSECT.equals(query.getType())) {
                return RestResponse.succeed(
                        spatialAnalysisService.intersectByGeoJson(dbTypeName, instanceName, tableId, query, "py2"));
            }
        }

        throw new ServiceException(ExceptionMsg.CLIENT_ERROR, "the format of geoJson is invalid");
    }

    @ApiOperation(value = "空间叠加分析，以输入图形做面与面的叠加")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "instanceName", value = "数据库连接实例名，例如zyk_dbfgc", paramType = "path", required = true),
            @ApiImplicitParam(name = "tableId", value = "表ID，带表空间名。例如sde.bgdc_dltb_gjxfb_2022", paramType = "path", required = true),
            @ApiImplicitParam(name = "query", value = "geoJson叠加分析查询对象", paramType = "body", required = true, dataType = "GeoJsonQuery")
    })
    @PostMapping(value = "/intersectpy/{instanceName}/{tableId:.*}")
    public RestResponse intersectPYByGeoJson(@PathVariable String instanceName, @PathVariable String tableId, @RequestBody GeoJsonQuery query)
            throws ExecutionException, InterruptedException {
        System.out.println();
        String beginTime = sdf.format(new Date());
        System.out.println("*******************提交处理请求*******************," + beginTime);

        //DBConfig dbConfig = dynamicDBConfig.get(instanceName);
        //String dbTypeName = dbConfig.getDbTypeName();
        JdbcConfig jdbcConfig= dbConfig.getJdbcCconfigByDbKey(instanceName);
        String dbTypeName = jdbcConfig.getDbtypename();

        if (query.getGeoJson().trim().startsWith("{")) {
            if (query.getDigits() == null) {
                query.setDigits(2);
            }
            if (AnalysisType.INTERSECT.equals(query.getType())) {
                return RestResponse.succeed(
                        spatialAnalysisService.intersectByGeoJson(dbTypeName,instanceName, tableId, query, "py"));
            }
        }

        throw new ServiceException(ExceptionMsg.CLIENT_ERROR, "the format of geoJson is invalid");
    }

    @ApiOperation(value = "空间叠加分析，以输入图形做面与线的叠加分析")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "instanceName", value = "数据库连接实例名，例如zyk_dbfgc", paramType = "path", required = true),
            @ApiImplicitParam(name = "tableId", value = "表ID，带表空间名。例如sde.bgdc_dltb_gjxfb_2022", paramType = "path", required = true),
            @ApiImplicitParam(name = "query", value = "geoJson叠加分析查询对象", paramType = "body", required = true, dataType = "GeoJsonQuery")
    })
    @PostMapping(value = "/intersectpl/{instanceName}/{tableId:.*}")
    public RestResponse intersectPLByGeoJson(@PathVariable String instanceName, @PathVariable String tableId, @RequestBody GeoJsonQuery query)
            throws ExecutionException, InterruptedException {
        System.out.println();
        String beginTime = sdf.format(new Date());
        System.out.println("*******************提交处理请求*******************," + beginTime);

        JdbcConfig jdbcConfig= dbConfig.getJdbcCconfigByDbKey(instanceName);
        String dbTypeName = jdbcConfig.getDbtypename();

        if (query.getGeoJson().trim().startsWith("{")) {
            if (query.getDigits() == null) {
                query.setDigits(2);
            }
            if (AnalysisType.INTERSECT.equals(query.getType())) {
                return RestResponse.succeed(
                        spatialAnalysisService.intersectByGeoJson(dbTypeName, instanceName, tableId, query, "pl"));
            }
        }

        throw new ServiceException(ExceptionMsg.CLIENT_ERROR, "the format of geoJson is invalid");
    }

    @ApiOperation(value = "空间叠加分析，以输入图形做面与点的叠加分析")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "instanceName", value = "数据库连接实例名，例如zyk_dbfgc", paramType = "path", required = true),
            @ApiImplicitParam(name = "tableId", value = "表ID，带表空间名。例如sde.bgdc_dltb_gjxfb_2022", paramType = "path", required = true),
            @ApiImplicitParam(name = "query", value = "geoJson叠加分析查询对象", paramType = "body", required = true, dataType = "GeoJsonQuery")
    })
    @PostMapping(value = "/intersectpt/{instanceName}/{tableId:.*}")
    public RestResponse intersectPTByGeoJson(@PathVariable String instanceName, @PathVariable String tableId, @RequestBody GeoJsonQuery query)
            throws ExecutionException, InterruptedException {
        System.out.println();
        String beginTime = sdf.format(new Date());
        System.out.println("*******************提交处理请求*******************," + beginTime);

        JdbcConfig jdbcConfig= dbConfig.getJdbcCconfigByDbKey(instanceName);
        String dbTypeName = jdbcConfig.getDbtypename();

        if (query.getGeoJson().trim().startsWith("{")) {
            if (query.getDigits() == null) {
                query.setDigits(2);
            }
            if (AnalysisType.INTERSECT.equals(query.getType())) {
                return RestResponse.succeed(
                        spatialAnalysisService.intersectByGeoJson(dbTypeName, instanceName, tableId, query, "pt"));
            }
        }

        throw new ServiceException(ExceptionMsg.CLIENT_ERROR, "the format of geoJson is invalid");
    }

    @ApiOperation(value = "以输入表做叠加")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "instanceName", value = "数据库连接实例名，例如zyk_dbfgc", paramType = "path", required = true),
            @ApiImplicitParam(name = "query", value = "表叠加分析查询对象", paramType = "body", required = true, dataType = "TableQuery")
    })
    @PostMapping(value = "/intersectByTable/{instanceName}")
    public RestResponse intersectByTable(@PathVariable String instanceName, @RequestBody TableQuery query)
            throws ExecutionException, InterruptedException {

        JdbcConfig jdbcConfig= dbConfig.getJdbcCconfigByDbKey(instanceName);
        String dbTypeName = jdbcConfig.getDbtypename();

        if (StringUtil.isNullOrEmpty(query.getOverlaidTableId()) || StringUtil.isNullOrEmpty(query.getOverlayTableId())) {
            throw new ServiceException(ExceptionMsg.CLIENT_ERROR, "the id of table can not be null or empty");
        }

        return RestResponse.succeed(AnalysisType.INTERSECT.equals(query.getType())
                ? spatialAnalysisService.intersectByTable(dbTypeName, instanceName, query)
                : spatialAnalysisService.differenceByTable(dbTypeName, instanceName, query));
    }

    @ApiOperation(value = "空间擦除，传入图形GeoJson")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "instanceName", value = "数据库连接实例名，例如zyk_dbfgc", paramType = "path", required = true),
            @ApiImplicitParam(name = "tableId", value = "表ID，带表空间名。例如sde.bgdc_dltb_gjxfb_2022", paramType = "path", required = true),
            @ApiImplicitParam(name = "query", value = "geoJson叠加分析查询对象", paramType = "body", required = true, dataType = "GeoJsonQuery")
    })
    @RequestMapping(value = "/difference/{instanceName}/{tableId:.*}", method = RequestMethod.POST)
    public RestResponse difference(@PathVariable String instanceName, @PathVariable String tableId, @RequestBody GeoJsonQuery query)
            throws ExecutionException, InterruptedException {

        JdbcConfig jdbcConfig= dbConfig.getJdbcCconfigByDbKey(instanceName);
        String dbTypeName = jdbcConfig.getDbtypename();

        if (query.getGeoJson().trim().startsWith("{")) {
            if (query.getDigits() == null) {
                query.setDigits(4);
            }

            if (AnalysisType.DIFFERENCE.equals(query.getType())) {
                return RestResponse.succeed(
                        spatialAnalysisService.differenceByGeoJson(dbTypeName, instanceName, tableId, query));
            }
        }

        throw new ServiceException(ExceptionMsg.CLIENT_ERROR, "the format of geoJson is invalid");
    }

    @ApiOperation(value = "空间擦除,传入表Id")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "instanceName", value = "实例名，例如zyk_dbfgc", paramType = "query", required = true),
            @ApiImplicitParam(name = "query", value = "表叠加分析查询对象", paramType = "body", required = true, dataType = "TableQuery")
    })
    @RequestMapping(value = "/difference/{instanceName:.*}", method = RequestMethod.POST)
    public RestResponse differenceByTable(@PathVariable String instanceName, @RequestBody TableQuery query)
            throws ExecutionException, InterruptedException {

        JdbcConfig jdbcConfig= dbConfig.getJdbcCconfigByDbKey(instanceName);
        String dbTypeName = jdbcConfig.getDbtypename();

        if (StringUtil.isNullOrEmpty(query.getOverlaidTableId()) || StringUtil.isNullOrEmpty(query.getOverlayTableId())) {
            throw new ServiceException(ExceptionMsg.CLIENT_ERROR, "the id of table can not be null or empty");
        }

        if (AnalysisType.DIFFERENCE.equals(query.getType())) {
            GeoJson[] res = spatialAnalysisService.differenceByTable(dbTypeName, instanceName, query);
            return RestResponse.succeed(res);
        }

        throw new ServiceException(ExceptionMsg.CLIENT_ERROR, "differenceByTable is failed");
    }
}
